/*
 * @Date: 2023-01-22 09:53:10
 * @LastEditors: 恶名扬 2080156129@qq.com
 * @LastEditTime: 2023-01-24 02:05:21
 * @FilePath: \campus-repair-platform\server\common\distribution.js
 */
const { send } = require("./short_message")
const repairStatement = require("./sql_sentences/repair")
const repairerStatement = require("./sql_sentences/repairer")
const repairTypeStatement = require("./sql_sentences/repair_type")

/**
 * 
 * @param {*} id 报修单id
 * @param {*} t_id 维修类型id
 * @param {*} a_number  管理员工号
 * @param {*} a_id  报修区域id
 * @returns 
 */
exports.repairman = (id, t_id, a_number, a_id) => {
  return new Promise(async (resolve, reject) => {
    try {
      // 获取当前报修类型的维修人员类型
      if (!t_id) return resolve({ message: "该报修类型不存在！", code: 10005 })
      const type_id = await fatherType(t_id, "")
      if (!type_id) return resolve({ message: "获得当前报修类型的维修人员类型失败！", code: 10005 })

      // 获取属于该类型的维修人员
      let sqlStr = repairerStatement.select({ type_id, state: 0 })
      let repairers = await RunSQL(sqlStr)
      if (!repairers.length) return resolve({ message: "该报修类型没有维修人员！", code: 10005 })

      // 获取当前待维修报修单
      sqlStr = repairStatement.selectGroup(' and state = 3 or state = 4', 1, 'r_number, a_id')
      let repairs = await RunSQL(sqlStr)

      // 修改报修单状态和信息
      sqlStr = repairStatement.idUpdate({ state: 4, r_number: (repairs.length ? finder(repairers, repairs, a_id) : repairers[0].job_number), a_number }, id)
      // send(id)
      let results = await RunSQL(sqlStr)
      if (results.affectedRows !== 1)
        return resolve({ message: "修改报修单状态失败！", code: 10005 })
      resolve({ message: "分配维修人员成功！", code: 10000 })
    } catch (error) {
      reject(error)
    }
  })
}

// 获得传入报修类型的维修人员类型
async function fatherType (type_id) {
  let results = await RunSQL(repairTypeStatement.idSelect(type_id))
  if (!results[0]?.id) return false
  if (!results[0]?.pid && results[0].r_type_id) return results[0].r_type_id
  return fatherType(results[0]?.pid)
}

// 获得维修人员类型中负责报修单较少的维修人员
function finder (repairers, repairs, a_id) {
  if (repairers.length === 1) return repairers[0].job_number
  let repairerObj = {}
  repairers = repairers.map((obj) => {
    repairerObj[obj.job_number] = { area: 0, num: 0, r_number: obj.job_number }
    return obj.job_number
  })
  repairs.forEach(item => {
    if (repairers.indexOf(item.r_number) >= 0) {
      item.a_id === a_id && repairerObj[item.r_number].area++
      repairerObj[item.r_number].num += item.cont
    }
  })
  let repairer = repairerObj[repairers[0]]
  if (repairers.length > 1 && repairer.num !== 0) {
    for (let i of Object.values(repairerObj)) {
      if (i.num === 0) return i.r_number
      else if (i.num < repairer.num) repairer = i
      else if (i.num === repairer.num && i.area) repairer = i
    }
  }
  return repairer.r_number
}